package com.csair.seam.infrastructure.sso;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.csair.seam.infrastructure.log.LoginLogInfo;
import com.csair.seam.infrastructure.utils.DateHelper;
import com.csair.seam.infrastructure.utils.WebUtil;
import com.trs.idm.client.actor.AbstractServletAppActor;
import com.trs.idm.client.actor.SSOUser;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CustomSsoActor extends AbstractServletAppActor {

  private static final String COOKIE_KEY_COSESSIONID = "com.trs.idm.coSessionId";
  private static final String COOKIE_KEY_GSESSIONID = "com.trs.idm.gSessionId";
  private static final String COOKIE_KEY_JSESSIONID = "JSESSIONID";
  public static final String SESSION_KEY_ACCOUNT = "sso.account";

  @Override
  public boolean addUser(SSOUser user, HttpServletRequest req) {
    return true;
  }

  @Override
  public boolean disableUser(SSOUser user) {
    return false;
  }

  @Override
  public boolean enableUser(SSOUser user) {
    return true;
  }

  @Override
  public String extractUserName(HttpServletRequest req) {
    HttpSession session = req.getSession();
    return (String) session.getAttribute(SESSION_KEY_ACCOUNT);
  }

  @Override
  public String extractUserPwd(HttpServletRequest req) {
    return null;
  }

  @Override
  public boolean removeUser(SSOUser user, HttpServletRequest req) {
    return true;
  }

  @Override
  public boolean updateUser(SSOUser user, HttpServletRequest req) {
    return true;
  }

  @Override
  public boolean userExist(SSOUser user) {
    return true;
  }

  @Override
  public boolean checkLocalLogin(HttpServletRequest req) {
    HttpSession session = req.getSession();
    return checkLocalLogin(session);
  }

  private boolean checkLocalLogin(HttpSession session) {
    String account = (String) session.getAttribute(SESSION_KEY_ACCOUNT);
    return StringUtils.isNotBlank(account);
  }

  @Override
  public void loadLoginUser(HttpServletRequest req, HttpServletResponse resp, SSOUser user) {
    loadLoginUser(req, user);
  }

  /**
   * Add account to session as login certificate.
   *
   * @param req HttpServletRequest
   * @param user SSOUser
   */
  private void loadLoginUser(HttpServletRequest req, SSOUser user) {
    HttpSession session = req.getSession();
    String account = user.getUserName();
    session.setAttribute(SESSION_KEY_ACCOUNT, account);
  }

  @Override
  public void logout(HttpServletRequest req, HttpServletResponse resp) {
    logout(req);
  }

  private void logout(HttpServletRequest req) {
	  HttpSession session = req.getSession();
	  Object accountObj = session.getAttribute(SESSION_KEY_ACCOUNT);
	  if(accountObj != null) {
		  session.removeAttribute(SESSION_KEY_ACCOUNT);
		  session.invalidate();
		  log.info("【用户登出】：{}",JSON.toJSONString(new LoginLogInfo(DateHelper.getCurrentDateTimeStr(), WebUtil.getIpAddress(req), String.valueOf(accountObj))));
	  }
  }

  private boolean isCookieNotEmpty(Cookie cookie) {
    return cookie != null && StringUtils.isNotBlank(cookie.getValue());
  }

  @Override
  public String getSessionId(HttpServletRequest req, HttpServletResponse resp, boolean create) {
    String gid = req.getParameter(COOKIE_KEY_GSESSIONID);
    if (gid != null) {
      return gid;
    }
    Cookie cookie;
    cookie = getCookie(req, COOKIE_KEY_COSESSIONID);
    if (isCookieNotEmpty(cookie)) {
      return cookie.getValue();
    }
    cookie = getCookie(req, COOKIE_KEY_JSESSIONID);
    if (isCookieNotEmpty(cookie)) {
      return cookie.getValue();
    }
    return req.getSession(create).getId();
  }

  @Override
  public void loadAnonymous(HttpServletRequest req) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean useStandardHttpSession() {
    return true;
  }

  private Cookie getCookie(HttpServletRequest req, String key) {
    if (StringUtils.isNotBlank(key)) {
      return null;
    }
    Cookie[] cookies = req.getCookies();
    if (cookies == null) {
      return null;
    }
    for (int i = cookies.length - 1; i >= 0; i--) {
      Cookie cookie = cookies[i];
      String name = cookie.getName();
      if (key.equals(name)) {
        return cookie;
      }
    }
    return null;
  }
}
